using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace ZombieHigh2.Primitive
{
    struct TexConsts
    {
        public static int TEXCOORD_ULEFT = 0;
        public static int TEXCOORD_URIGHT = 1;
        public static int TEXCOORD_LRIGHT = 2;
        public static int TEXCOORD_LLEFT = 3;
    }

    public class TexturedQuad
    {
        public Vector3 _origin;
        public Vector3 _upperLeft;
        public Vector3 _upperRight;
        public Vector3 _lowerLeft;
        public Vector3 _lowerRight;
        public Vector3 _normal;
        public Vector3 _up;
        public Vector3 _left;
        public float _width;
        public float _height;

        public VertexPositionNormalTexture[] _vertices;
        public int[] _indices;

        bool _flipped;

        protected Vector2[] textureCoords;
        protected Vector2[] renderCoords;       //coordinates used for rendering

        public bool Flipped
        {
            get { return _flipped; }
            set { _flipped = value; FillVertices(); }
        }

        public Vector3 Position
        {
            get { return _origin; }
            set { SetOrigin(value); }
        }

        public TexturedQuad(Vector3 origin, Vector3 normal, Vector3 up, float width, float height)
        {
            _vertices = new VertexPositionNormalTexture[4];
            _indices = new int[6];
            _normal = normal;
            _up = up;
            _width = width;
            _height = height;
            _flipped = false;

            SetOrigin(origin);
            
            textureCoords = new Vector2[4];
            renderCoords = new Vector2[4];

            textureCoords[TexConsts.TEXCOORD_ULEFT] = new Vector2(0, 0);
            textureCoords[TexConsts.TEXCOORD_URIGHT] = new Vector2(1, 0);
            textureCoords[TexConsts.TEXCOORD_LLEFT] = new Vector2(0, 1);
            textureCoords[TexConsts.TEXCOORD_LRIGHT] = new Vector2(1, 1);

            for (int i = 0; i < _vertices.Length; i++)
            {
                _vertices[i].Normal = _normal;
            }

            _vertices[0].Position = _lowerLeft;
            _vertices[0].TextureCoordinate = textureCoords[TexConsts.TEXCOORD_LLEFT];
            _vertices[1].Position = _upperLeft;
            _vertices[1].TextureCoordinate = textureCoords[TexConsts.TEXCOORD_ULEFT];
            _vertices[2].Position = _upperRight;
            _vertices[2].TextureCoordinate = textureCoords[TexConsts.TEXCOORD_URIGHT];
            _vertices[3].Position = _lowerRight;
            _vertices[3].TextureCoordinate = textureCoords[TexConsts.TEXCOORD_LRIGHT];

            //set the indicies, clockwise winding
            _indices[0] = 0;
            _indices[1] = 1;
            _indices[2] = 2;
            _indices[3] = 2;
            _indices[4] = 3;
            _indices[5] = 0;

            //FillVertices();
        }

        protected void SetOrigin(Vector3 origin)
        {
            _origin = origin;

            //calculate quad corners
            _left = Vector3.Cross(_normal, _up);
            Vector3 upperCentre = (_up * _height / 2) + _origin;
            _upperLeft = upperCentre + (_left * _width / 2);
            _upperRight = upperCentre - (_left * _width / 2);
            _lowerLeft = _upperLeft - (_up * _height);
            _lowerRight = _upperRight - (_up * _height);

        }

        protected void FillVertices()
        {
            //for (int i = 0; i < _vertices.Length; i++)
            //{
            //    _vertices[i].Normal = _normal;
            //}

            if (_flipped)
            {
                renderCoords[TexConsts.TEXCOORD_ULEFT] = textureCoords[TexConsts.TEXCOORD_URIGHT];
                renderCoords[TexConsts.TEXCOORD_URIGHT] = textureCoords[TexConsts.TEXCOORD_ULEFT];
                renderCoords[TexConsts.TEXCOORD_LLEFT] = textureCoords[TexConsts.TEXCOORD_LRIGHT];
                renderCoords[TexConsts.TEXCOORD_LRIGHT] = textureCoords[TexConsts.TEXCOORD_LLEFT];

            }
            else
            {
                renderCoords[TexConsts.TEXCOORD_ULEFT] = textureCoords[TexConsts.TEXCOORD_ULEFT];
                renderCoords[TexConsts.TEXCOORD_URIGHT] = textureCoords[TexConsts.TEXCOORD_URIGHT];
                renderCoords[TexConsts.TEXCOORD_LLEFT] = textureCoords[TexConsts.TEXCOORD_LLEFT];
                renderCoords[TexConsts.TEXCOORD_LRIGHT] = textureCoords[TexConsts.TEXCOORD_LRIGHT];
            }

            //set position and texture coordinate for each vertex
            //_vertices[0].Position = _lowerLeft;
            _vertices[0].TextureCoordinate = renderCoords[TexConsts.TEXCOORD_LLEFT];
            //_vertices[1].Position = _upperLeft;
            _vertices[1].TextureCoordinate = renderCoords[TexConsts.TEXCOORD_ULEFT];
            //_vertices[2].Position = _upperRight;
            _vertices[2].TextureCoordinate = renderCoords[TexConsts.TEXCOORD_URIGHT];
            //_vertices[3].Position = _lowerRight;
            _vertices[3].TextureCoordinate = renderCoords[TexConsts.TEXCOORD_LRIGHT];

            //set the indicies, clockwise winding
            //_indices[0] = 0;
            //_indices[1] = 1;
            //_indices[2] = 2;
            //_indices[3] = 2;
            //_indices[4] = 3;
            //_indices[5] = 0;
        }

        public virtual void Draw(GraphicsDevice device)
        {
            device.DrawUserIndexedPrimitives<VertexPositionNormalTexture>(PrimitiveType.TriangleList,
                    _vertices, 0, 4, _indices, 0, 2);

        }
    }

    public class AnimatedQuad : TexturedQuad
    {
        public int SheetWidth;
        public int SheetHeight;
        public int CurrentFrame;
        public int FrameWidth;
        public int FrameHeight;
        public int FramesPerRow;

        public AnimatedQuad(Vector3 origin, Vector3 normal, Vector3 up,
            float width, float height, int sheetWidth, int sheetHeight, int frameWidth, int frameHeight)
            : base(origin, normal, up, width, height)
        {
            SheetWidth = sheetWidth;
            SheetHeight = sheetHeight;
            FrameWidth = frameWidth;
            FrameHeight = frameHeight;

            FramesPerRow = SheetWidth / FrameWidth;
        }

        public void SetFrame(int frame)
        {            
            int left = frame % FramesPerRow * FrameWidth;
            int row = (int)(System.Math.Floor((float)(frame / FramesPerRow)) * (float)FrameHeight);

            if (frame == 5)
            {
                frame = 5;
            }

            float l, t, r, b;

            l = (float)left / (float)SheetWidth;
            t = (float)row / (float)SheetHeight;
            r = (float)(left + FrameWidth) / (float)SheetWidth;
            b = (float)(row + FrameHeight) / (float)SheetHeight;

            textureCoords[TexConsts.TEXCOORD_ULEFT] = new Vector2(l, t);
            textureCoords[TexConsts.TEXCOORD_LLEFT] = new Vector2(l, b);
            textureCoords[TexConsts.TEXCOORD_LRIGHT] = new Vector2(r, b);
            textureCoords[TexConsts.TEXCOORD_URIGHT] = new Vector2(r, t);

            FillVertices();
        }

        

    }

}
